#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <map>
#include <set>
#include <vector>

template <typename T>
inline T &read(T &x) {
  x = 0;
  bool f = false;
  short ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = true;
    ch = getchar();
  }
  while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ '0'), ch = getchar();
  if (f) x = -x;
  return x;
}

const int N = 1e5 + 5, mod = 1e9 + 7;
int n, cnt, a[N], nxt[N], wz[N], sum, gg[N], num, vis[N], pri[N];

using namespace std;
map<int, int> list;
vector<int> gh;

struct T { //区间和 区间乘
  int l, r, tag, sum;
} tree[N << 2];

int getgcd(int a, int b) { return b == 0 ? a : getgcd(b, a % b); }

inline void pushdown(int p) {
  if (!tree[p].tag) return;
  tree[p << 1].sum = 1ll * tree[p << 1].sum * tree[p].tag % mod;
  if (!tree[p << 1].tag) tree[p << 1].tag = 1;
  tree[p << 1].tag = 1ll * tree[p << 1].tag * tree[p].tag % mod;
  tree[p << 1 | 1].sum = 1ll * tree[p << 1 | 1].sum * tree[p].tag % mod;
  if (!tree[p << 1 | 1].tag) tree[p << 1 | 1].tag = 1;
  tree[p << 1 | 1].tag = 1ll * tree[p << 1 | 1].tag * tree[p].tag % mod;
  tree[p].tag = 0;
}

inline void pushup(int p) {
  tree[p].sum = tree[p << 1].sum + tree[p << 1 | 1].sum;
}

void build(int p, int l, int r) {
  tree[p].l = l, tree[p].r = r, tree[p].sum = tree[p].tag = 0;
  if (l == r) {
    tree[p].sum = 1;
    tree[p].tag = 0;
    return;
  }
  int mid = (l + r) >> 1;
  build(p << 1, l, mid);
  build(p << 1 | 1, mid + 1, r);
  pushup(p);
}

void modify(int p, int l, int r, int L, int R, int x) {
  if (L <= l && r <= R) {
    tree[p].sum = 1ll * tree[p].sum * x % mod;
    if (!tree[p].tag) tree[p].tag = 1;
    tree[p].tag = 1ll * tree[p].tag * x % mod;
    return;
  }
  pushdown(p);
  int mid = (l + r) >> 1;
  if (L <= mid) modify(p << 1, l, mid, L, R, x);
  if (mid < R) modify(p << 1 | 1, mid + 1, r, L, R, x);
  pushup(p);
}

inline void divide(int x) {
  gh.clear();
  for (int i = 1; pri[i] * pri[i] <= x; ++i)
    if (x % pri[i] == 0) {
      while (x % pri[i] == 0) gh.push_back(pri[i]), x /= pri[i];
    }
  if (x != 1) gh.push_back(x);
}

void work(int l, int r) {
  if (l == r) { return sum = (sum + a[l]) % mod, void(); }
  int mid = (l + r) >> 1;
  work(l, mid);
  work(mid + 1, r);

  gg[mid] = a[mid];
  for (int i = mid - 1; i >= l; --i) gg[i] = getgcd(gg[i + 1], a[i]);
  gg[mid + 1] = a[mid + 1];
  for (int i = mid + 2; i <= r; ++i) gg[i] = getgcd(gg[i - 1], a[i]);

  set<int> del;
  num = 0;
  gg[l - 1] = 1;
  for (int i = mid; i >= l; --i) {
    int yu = gg[i] / gg[i - 1];
    if (yu == 1) continue;
    divide(yu);
    for (int j = 0; j < gh.size(); ++j) {
      nxt[++num] = list[gh[j]];
      wz[num] = i;
      list[gh[j]] = num;
      del.insert(gh[j]);
    }
  }

  build(1, l, mid);
  gg[r + 1] = 1;
  for (int i = r; i >= mid + 1; --i) {
    int yu = gg[i] / gg[i + 1];
    if (yu == 1) {
      sum = (sum + tree[1].sum) % mod;
      continue;
    }
    divide(yu);
    for (int j = 0; j < gh.size(); ++j) {
      if (!list[gh[j]]) continue;
      modify(1, l, mid, wz[list[gh[j]]], mid, gh[j]);
      list[gh[j]] = nxt[list[gh[j]]];
    }
    sum = (sum + tree[1].sum) % mod;
  }
  for (set<int>::iterator it = del.begin(); it != del.end(); ++it)
    list[*it] = 0;
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen64("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen64("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("getgcd.in", "r", stdin);
  freopen("getgcd.out", "w", stdout);
#endif
#endif

  for (int i = 2; i < N; ++i) {
    if (!vis[i]) pri[++cnt] = i;
    for (int j = 1; j <= cnt && i * pri[j] < N; ++j) {
      vis[i * pri[j]] = true;
      if (i % pri[j] == 0) break;
    }
  }
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) read(a[i]);
  work(1, n);
  printf("%d", sum);
  return 0;
}